using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using ShareTools.Common;

namespace ShareTools.InfoPathFormsLib
{
    public class FormsContentTypeManager
    {
        string siteURL;

        public string SiteURL
        {
            get { return siteURL; }
            set { siteURL = value; }
        }

        System.Collections.Hashtable ctHashtable = new System.Collections.Hashtable();

        public System.Collections.Hashtable GetFormContentTypesList()
        {
            List<FormContentType> formCTList = null; // new List<FormContentType>();
            FormContentType fCT = new FormContentType();

            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentTypeCollection ctCollection = web.ContentTypes;
                    foreach (SPContentType ct in ctCollection)
                    {
                        if (!ctHashtable.Contains(ct.Group))
                        {
                            formCTList = new List<FormContentType>();
                            ctHashtable.Add(ct.Group, formCTList);
                        }
                        fCT = new FormContentType();
                        fCT.Name = ct.Name;
                        fCT.ContentTypeID = ct.Id.ToString();
                        fCT.GroupName = ct.Group;
                        fCT.WorkflowAssociationsCount = ct.WorkflowAssociations.Count;
                        if (fCT.WorkflowAssociationsCount > 0)
                        {
                            fCT.WorkflowNames = new List<string>();
                            foreach (SPWorkflowAssociation assoc in ct.WorkflowAssociations)
                            {
                                fCT.WorkflowNames.Add(assoc.Name + "(" + assoc.BaseTemplate.Name +")");
                            }
                        }
                        if (formCTList == null) formCTList = ctHashtable[ct.Group] as List<FormContentType>;
                        formCTList.Add(fCT);
                    }
                    web.Close();
                }
                site.Close();
            }
            return ctHashtable;
        }

        public FormContentType GetContentTypeByName(string name)
        {
            FormContentType fCT = null;
            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentType ct = web.ContentTypes[name];
                    fCT = new FormContentType();
                    fCT.Name = ct.Name;
                    fCT.ContentTypeID = ct.Id.ToString();
                    fCT.GroupName = ct.Group;
                    fCT.WorkflowAssociationsCount = ct.WorkflowAssociations.Count;
                }
            }
            return fCT;
        }

        public List<WorkflowItem> GetWorkflowsAvailable()
        {
            List<WorkflowItem> wfItemsList = new List<WorkflowItem>();
            WorkflowItem wfItem = null;
            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    //SPWorkflowCollection spWFCollection = web.WorkflowTemplates();
                    SPWorkflowTemplateCollection spWFTC = site.WorkflowManager.GetWorkflowTemplatesByCategory(web, null);
                    foreach (SPWorkflowTemplate spWFT in spWFTC)
                    {
                        wfItem = new WorkflowItem();
                        wfItem.Name = spWFT.Name;
                        wfItem.Id = spWFT.Id;
                        wfItemsList.Add(wfItem);
                    }
                }
            }
            return wfItemsList;
        }

        public void AddWorkflowAssociation(FormContentType fCT, string wfTemplateName, string tasksListName, string historyListName, string wfName)
        {
            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    try
                    {
                        SPContentType ct = web.ContentTypes[fCT.Name];
                        if (ct.WorkflowAssociations.Count > 0)
                        {
                            foreach (SPWorkflowAssociation assoc in ct.WorkflowAssociations)
                            {
                                if (assoc.Name.Equals(wfName)) //this association already is existing
                                {
                                    ct.RemoveWorkflowAssociation(assoc);
                                    break;
                                }
                            }
                        }
                        SPWorkflowTemplateCollection templates = site.WorkflowManager.GetWorkflowTemplatesByCategory(web, null);
                        SPWorkflowTemplate wfTemplate = templates.GetTemplateByName(wfTemplateName, System.Globalization.CultureInfo.CurrentCulture);
                        SPWorkflowAssociation association = SPWorkflowAssociation.CreateSiteContentTypeAssociation(wfTemplate, wfName, tasksListName, historyListName);
                        association.AutoStartCreate = true;
                        ct.AddWorkflowAssociation(association);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }
        }

        public void AddWorkflowAssociation(List<FormContentType> fCTList, string wfTemplateName, string tasksListName, string historyListName, string wfName)
        {
            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    foreach (FormContentType fCT in fCTList)
                    {
                        try
                        {
                            SPContentType ct = web.ContentTypes[fCT.Name];
                            if (ct.WorkflowAssociations.Count > 0)
                            {
                                foreach (SPWorkflowAssociation assoc in ct.WorkflowAssociations)
                                {
                                    if (assoc.Name.Equals(wfName)) //this association already is existing
                                    {
                                        ct.RemoveWorkflowAssociation(assoc);
                                        break;
                                    }
                                }
                            }
                            SPWorkflowTemplateCollection templates = site.WorkflowManager.GetWorkflowTemplatesByCategory(web, null);
                            SPWorkflowTemplate wfTemplate = templates.GetTemplateByName(wfTemplateName, System.Globalization.CultureInfo.CurrentCulture);
                            SPWorkflowAssociation association = SPWorkflowAssociation.CreateSiteContentTypeAssociation(wfTemplate, wfName, tasksListName, historyListName);
                            association.AutoStartCreate = true;
                            ct.AddWorkflowAssociation(association);
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                }
            }
        }

        public void RemoveWorkflowAssociation(List<FormContentType> fCTList, string wfName)
        {
            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    try
                    {
                        foreach (FormContentType fCT in fCTList)
                        {
                            SPContentType ct = web.ContentTypes[fCT.Name];
                            if (ct.WorkflowAssociations.Count > 0)
                            {
                                foreach (SPWorkflowAssociation assoc in ct.WorkflowAssociations)
                                {
                                    if (assoc.Name.Equals(wfName)) //this association already is existing
                                    {
                                        ct.RemoveWorkflowAssociation(assoc);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }

        public void RemoveWorkflowAssociation(FormContentType fCT, string wfName)
        {
            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    try
                    {
                        SPContentType ct = web.ContentTypes[fCT.Name];
                        if (ct.WorkflowAssociations.Count > 0)
                        {
                            foreach (SPWorkflowAssociation assoc in ct.WorkflowAssociations)
                            {
                                if (assoc.Name.Equals(wfName)) //this association already is existing
                                {
                                    ct.RemoveWorkflowAssociation(assoc);
                                    break;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }
    }
}
